import { z } from 'zod';
import { prisma } from '../db/prisma';
import { createSuccessResponse, createErrorResponse } from '../utils/response';
import { MarketType, TerminalType } from '@prisma/client';

// 输入验证模式
const createClientSchema = z.object({
  clientCode: z.string().min(1).max(12),
  clientName: z.string().min(1).max(100),
  marketType: z.nativeEnum(MarketType),
  terminalType: z.nativeEnum(TerminalType),
});

const updateClientSchema = z.object({
  id: z.number().int().positive(),
  clientCode: z.string().min(1).max(12).optional(),
  clientName: z.string().min(1).max(100).optional(),
  marketType: z.nativeEnum(MarketType).optional(),
  terminalType: z.nativeEnum(TerminalType).optional(),
});

const deleteClientSchema = z.object({
  id: z.number().int().positive(),
});

const getClientSchema = z.object({
  id: z.number().int().positive(),
});

const listClientsSchema = z.object({
  page: z.number().int().positive().default(1),
  pageSize: z.number().int().positive().max(100).default(10),
  search: z.string().optional(),
});

const assignManagerSchema = z.object({
  clientId: z.number().int().positive(),
  managerId: z.number().int().positive(),
});

const unassignManagerSchema = z.object({
  clientId: z.number().int().positive(),
  managerId: z.number().int().positive(),
});

// 客户经理修改客户信息的验证模式
const managerUpdateClientSchema = z.object({
  managerId: z.number().int().positive(),
  clientId: z.number().int().positive(),
  clientName: z.string().min(1).max(100).optional(),
  marketType: z.nativeEnum(MarketType).optional(),
  terminalType: z.nativeEnum(TerminalType).optional(),
});

export class ClientService {
  // 创建客户
  static async createClient(input: z.infer<typeof createClientSchema>) {
    try {
      const validatedInput = createClientSchema.parse(input);
      
      // 检查客户编码是否已存在
      const existingClient = await prisma.client.findFirst({
        where: { 
          clientCode: validatedInput.clientCode
        }
      });
      
      if (existingClient) {
        return createErrorResponse('客户编码已存在', 'CLIENT_CODE_EXISTS');
      }
      
      // 创建客户
      const client = await prisma.client.create({
        data: {
          clientCode: validatedInput.clientCode,
          clientName: validatedInput.clientName,
          marketType: validatedInput.marketType,
          terminalType: validatedInput.terminalType,
        },
        include: {
          _count: {
            select: {
              managerAssignments: true,
              serviceAssignments: true,
              workLogs: true,
            }
          }
        }
      });
      
      return createSuccessResponse(client, '客户创建成功');
    } catch (error) {
      console.error('创建客户失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('创建客户失败', 'CREATE_CLIENT_ERROR');
    }
  }

  // 更新客户
  static async updateClient(input: z.infer<typeof updateClientSchema>) {
    try {
      const validatedInput = updateClientSchema.parse(input);
      const { id, ...updateData } = validatedInput;
      
      // 检查客户是否存在
      const existingClient = await prisma.client.findUnique({
        where: { 
          id: id
        }
      });
      
      if (!existingClient) {
        return createErrorResponse('客户不存在', 'CLIENT_NOT_FOUND');
      }
      
      // 如果更新客户编码，检查是否重复
      if (updateData.clientCode && updateData.clientCode !== existingClient.clientCode) {
        const duplicateClient = await prisma.client.findFirst({
          where: { 
            clientCode: updateData.clientCode,
            id: { not: id }
          }
        });
        
        if (duplicateClient) {
          return createErrorResponse('客户编码已存在', 'CLIENT_CODE_EXISTS');
        }
      }
      
      // 更新客户
      const client = await prisma.client.update({
        where: { id: id },
        data: updateData,
        include: {
          _count: {
            select: {
              managerAssignments: true,
              serviceAssignments: true,
              workLogs: true,
            }
          }
        }
      });
      
      return createSuccessResponse(client, '客户更新成功');
    } catch (error) {
      console.error('更新客户失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('更新客户失败', 'UPDATE_CLIENT_ERROR');
    }
  }
  
  // 硬删除客户（级联删除相关数据）
  static async deleteClient(input: z.infer<typeof deleteClientSchema>) {
    try {
      const validatedInput = deleteClientSchema.parse(input);
      
      // 检查客户是否存在
      const existingClient = await prisma.client.findUnique({
        where: { 
          id: validatedInput.id
        }
      });
      
      if (!existingClient) {
        return createErrorResponse('客户不存在', 'CLIENT_NOT_FOUND');
      }
      
      // 直接硬删除客户（由于数据库外键约束设置了ON DELETE CASCADE，相关数据会自动级联删除）
      await prisma.client.delete({
        where: { id: validatedInput.id }
      });
      
      return createSuccessResponse(null, '客户删除成功');
    } catch (error) {
      console.error('删除客户失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('删除客户失败', 'DELETE_CLIENT_ERROR');
    }
  }
  
  // 获取单个客户
  static async getClient(input: z.infer<typeof getClientSchema>) {
    try {
      const validatedInput = getClientSchema.parse(input);
      
      const client = await prisma.client.findUnique({
        where: { 
          id: validatedInput.id
        },
        include: {
          managerAssignments: {
            include: {
              manager: {
                select: {
                  id: true,
                  username: true,
                  fullName: true,
                }
              }
            }
          },
          serviceAssignments: {
            include: {
              service: {
                select: {
                  id: true,
                  serviceName: true,
                  completionCycle: true,
                  cycleValue: true,
                }
              }
            }
          },
          _count: {
            select: {
              managerAssignments: true,
              serviceAssignments: true,
              workLogs: true,
            }
          }
        }
      });
      
      if (!client) {
        return createErrorResponse('客户不存在', 'CLIENT_NOT_FOUND');
      }
      
      return createSuccessResponse(client, '获取客户成功');
    } catch (error) {
      console.error('获取客户失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('获取客户失败', 'GET_CLIENT_ERROR');
    }
  }
  
  // 获取客户列表
  static async listClients(input: z.infer<typeof listClientsSchema>) {
    try {
      const validatedInput = listClientsSchema.parse(input);
      const { page, pageSize, search } = validatedInput;
      
      // 构建查询条件
      const where: any = {};
      
      if (search) {
        where.OR = [
          { clientCode: { contains: search } },
          { clientName: { contains: search } },
        ];
      }
      
      // 获取总数
      const total = await prisma.client.count({ where });
      
      // 获取分页数据
      const clients = await prisma.client.findMany({
        where,
        include: {
          managerAssignments: {
            include: {
              manager: {
                select: {
                  id: true,
                  username: true,
                  fullName: true,
                }
              }
            }
          },
          _count: {
            select: {
              managerAssignments: true,
              serviceAssignments: true,
              workLogs: true,
            }
          }
        },
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      });
      
      const result = {
        data: clients,
        pagination: {
          page,
          pageSize,
          total,
          totalPages: Math.ceil(total / pageSize),
        }
      };
      
      return createSuccessResponse(result, '获取客户列表成功');
    } catch (error) {
      console.error('获取客户列表失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('获取客户列表失败', 'LIST_CLIENTS_ERROR');
    }
  }

  // 分配客户经理
  static async assignManager(input: z.infer<typeof assignManagerSchema>) {
    try {
      const validatedInput = assignManagerSchema.parse(input);
      
      // 检查客户是否存在
      const client = await prisma.client.findUnique({
        where: { 
          id: validatedInput.clientId
        }
      });
      
      if (!client) {
        return createErrorResponse('客户不存在', 'CLIENT_NOT_FOUND');
      }
      
      // 检查客户经理是否存在
      const manager = await prisma.manager.findUnique({
        where: { id: validatedInput.managerId }
      });
      
      if (!manager) {
        return createErrorResponse('客户经理不存在', 'MANAGER_NOT_FOUND');
      }
      
      // 检查是否已经分配
      const existingAssignment = await prisma.managerClientAssignment.findUnique({
        where: {
          managerId_clientId: {
            managerId: validatedInput.managerId,
            clientId: validatedInput.clientId
          }
        }
      });
      
      if (existingAssignment) {
        return createErrorResponse('该客户已分配给此客户经理', 'ASSIGNMENT_EXISTS');
      }
      
      // 创建分配关系
      const assignment = await prisma.managerClientAssignment.create({
        data: {
          managerId: validatedInput.managerId,
          clientId: validatedInput.clientId,
        },
        include: {
          manager: {
            select: {
              id: true,
              username: true,
              fullName: true,
            }
          },
          client: {
            select: {
              id: true,
              clientCode: true,
              clientName: true,
            }
          }
        }
      });
      
      return createSuccessResponse(assignment, '客户经理分配成功');
    } catch (error) {
      console.error('分配客户经理失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('分配客户经理失败', 'ASSIGN_MANAGER_ERROR');
    }
  }

  // 取消分配客户经理
  static async unassignManager(input: z.infer<typeof unassignManagerSchema>) {
    try {
      const validatedInput = unassignManagerSchema.parse(input);
      
      // 检查分配关系是否存在
      const existingAssignment = await prisma.managerClientAssignment.findUnique({
        where: {
          managerId_clientId: {
            managerId: validatedInput.managerId,
            clientId: validatedInput.clientId
          }
        }
      });
      
      if (!existingAssignment) {
        return createErrorResponse('分配关系不存在', 'ASSIGNMENT_NOT_FOUND');
      }
      
      // 删除分配关系
      await prisma.managerClientAssignment.delete({
        where: {
          managerId_clientId: {
            managerId: validatedInput.managerId,
            clientId: validatedInput.clientId
          }
        }
      });
      
      return createSuccessResponse(null, '取消分配成功');
    } catch (error) {
      console.error('取消分配客户经理失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('取消分配客户经理失败', 'UNASSIGN_MANAGER_ERROR');
    }
  }

  // 客户经理修改客户信息（只能修改负责的客户）
  static async managerUpdateClient(input: z.infer<typeof managerUpdateClientSchema>) {
    try {
      const validatedInput = managerUpdateClientSchema.parse(input);
      const { managerId, clientId, ...updateData } = validatedInput;
      
      // 检查客户经理是否存在
      const manager = await prisma.manager.findUnique({
        where: { id: managerId }
      });
      
      if (!manager) {
        return createErrorResponse('客户经理不存在', 'MANAGER_NOT_FOUND');
      }
      
      // 检查客户是否存在
      const existingClient = await prisma.client.findUnique({
        where: { id: clientId }
      });
      
      if (!existingClient) {
        return createErrorResponse('客户不存在', 'CLIENT_NOT_FOUND');
      }
      
      // 检查客户经理是否负责该客户
      const assignment = await prisma.managerClientAssignment.findUnique({
        where: {
          managerId_clientId: {
            managerId: managerId,
            clientId: clientId
          }
        }
      });
      
      if (!assignment) {
        return createErrorResponse('您没有权限修改此客户信息', 'NO_PERMISSION');
      }
      
      // 过滤出实际需要更新的字段
      const actualUpdateData: any = {};
      if (updateData.clientName !== undefined) {
        actualUpdateData.clientName = updateData.clientName;
      }
      if (updateData.marketType !== undefined) {
        actualUpdateData.marketType = updateData.marketType;
      }
      if (updateData.terminalType !== undefined) {
        actualUpdateData.terminalType = updateData.terminalType;
      }
      
      // 如果没有需要更新的字段，直接返回成功
      if (Object.keys(actualUpdateData).length === 0) {
        return createSuccessResponse(existingClient, '客户信息未发生变化');
      }
      
      // 更新客户信息
      const updatedClient = await prisma.client.update({
        where: { id: clientId },
        data: actualUpdateData,
        include: {
          managerAssignments: {
            include: {
              manager: {
                select: {
                  id: true,
                  username: true,
                  fullName: true,
                }
              }
            }
          },
          _count: {
            select: {
              managerAssignments: true,
              serviceAssignments: true,
              workLogs: true,
            }
          }
        }
      });
      
      return createSuccessResponse(updatedClient, '客户信息修改成功');
    } catch (error) {
      console.error('客户经理修改客户信息失败:', error);
      if (error instanceof z.ZodError) {
        return createErrorResponse('输入数据验证失败', 'VALIDATION_ERROR', error.issues);
      }
      return createErrorResponse('修改客户信息失败', 'MANAGER_UPDATE_CLIENT_ERROR');
    }
  }
}
